package com.cs410.collabwriting.junit.servlets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import junit.framework.Assert;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;

import com.cs410.collabwriting.main.Story;
import com.cs410.collabwriting.main.StoryManager;
import com.cs410.collabwriting.main.User;
import com.cs410.collabwriting.main.UserManager;
import com.cs410.collabwriting.servlets.CreateHandler;
import com.cs410.collabwriting.test.DatabaseUtility;
import com.cs410.collabwriting.tools.LogManager;

public class CreateHandlerTest extends CreateHandler {

	private static String m_userInfo = "CREATEHANDLERTEST";
	private static User m_user;
	private static Story m_story;
	private static String s_jessionID = "ABCDEFGHJ";
	private static HttpClient httpclient = new DefaultHttpClient();
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		LogManager.logInfo("[JUnitTest] -- Starting JUnit Tests for CreateHandler" );
		DatabaseUtility.DeleteAllTables();
		Thread.sleep(1000);
		DatabaseUtility.CreateAllTables();
		Thread.sleep(1000);
		DatabaseUtility.CreateAllTestingData();
		Thread.sleep(10000);
		
		m_user = UserManager.getInstance().addUser( m_userInfo, m_userInfo, m_userInfo);
		Thread.sleep( 1000 );
		m_user.activateUser( m_user.getUserID(), m_user.getActivateKey() );
		Thread.sleep( 1000 );
		m_story = StoryManager.getInstance().createStory( "UPDATE_HANDLER_TEST", m_user.getUserID(), null );
		m_story.contributePost( m_user.getUserID(), "ABCDEFG");
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		DatabaseUtility.DeleteAllTables();
		LogManager.logInfo("[JUnitTest] -- Finished JUnit Tests for CreateHandler" );
	}

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {

	}

	@Test
	public void shareStoryListTest() throws IOException, InterruptedException {
		String URL = "http://localhost:8080/writeonproject/login?user=" + m_userInfo + "&password=" + m_userInfo + "&action=login";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains( "loggedIn\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?object=sharestorylist&listid=1&email=abc@bca.com";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"Email sent") );
		
		URL = "http://localhost:8080/writeonproject/create?object=sharestorylist&listid=1";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"Invalid email") );
	
		URL = "http://localhost:8080/writeonproject/login?action=logout";
		response = CreateHandlerTest.getServletCallResponse( URL );
	}
	
	@Test
	public void badObjectTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/login?user=" + m_userInfo + "&password=" + m_userInfo + "&action=login";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains( "loggedIn\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"No Object specified for creation!") );
		
		URL = "http://localhost:8080/writeonproject/create?object=AVERYBADOBJECT";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"Invalid Object Creation :") );
	
		URL = "http://localhost:8080/writeonproject/login?action=logout";
		response = CreateHandlerTest.getServletCallResponse( URL );	
	}
	

	@Test
	public void createNewStoryListTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/login?user=" + m_userInfo + "&password=" + m_userInfo + "&action=login";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains( "loggedIn\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?object=storylist&name=abcdefg";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("error\":\"false") );
		
		URL = "http://localhost:8080/writeonproject/create?object=storylist&name=";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"Name cannot be empty") );
	
		URL = "http://localhost:8080/writeonproject/login?action=logout";
		response = CreateHandlerTest.getServletCallResponse( URL );
	}
	
	@Test
	public void createNewCommentTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/login?user=" + m_userInfo + "&password=" + m_userInfo + "&action=login";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains( "loggedIn\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?object=comment&comment=abcdefg&storyid=" + m_story.getStoryID();
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("error\":\"false") );
		
		URL = "http://localhost:8080/writeonproject/create?object=comment";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"storyid can not be empty") );
	
		URL = "http://localhost:8080/writeonproject/login?action=logout";
		response = CreateHandlerTest.getServletCallResponse( URL );	
	}
	
	@Test
	public void createNewPostTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/login?user=" + m_userInfo + "&password=" + m_userInfo + "&action=login";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains( "loggedIn\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?object=post&post=abcdefg&tags=a,b,c&storyid=" + m_story.getStoryID();
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response, response.contains("error\":\"false") );
		
		URL = "http://localhost:8080/writeonproject/create?object=post&post=abcdefg";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"no story to contribute to!") );
		
		URL = "http://localhost:8080/writeonproject/create?object=post&storyid=" + m_story.getStoryID();
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"Empty posts are not allowed!") );
	
		URL = "http://localhost:8080/writeonproject/login?action=logout";
		response = CreateHandlerTest.getServletCallResponse( URL );	
	}
	
	@Test
	public void createNewStorySubTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/login?user=" + m_userInfo + "&password=" + m_userInfo + "&action=login";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains( "loggedIn\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?object=storysub&storyid=" + m_story.getStoryID();
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("error\":\"false") );
		
		URL = "http://localhost:8080/writeonproject/create?object=storysub";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"storyid cannot be empty") );
		
		URL = "http://localhost:8080/writeonproject/login?action=logout";
		response = CreateHandlerTest.getServletCallResponse( URL );
	}
	
	@Test
	public void createNewUpvoteTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/login?user=" + m_userInfo + "&password=" + m_userInfo + "&action=login";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains( "loggedIn\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?object=upvote&storyid=" + m_story.getStoryID();
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("error\":\"false") );
		
		URL = "http://localhost:8080/writeonproject/create?object=upvote&storyid=" + m_story.getStoryID();
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"story could not be upvoted") );
		
		URL = "http://localhost:8080/writeonproject/create?object=upvote";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"storyid cannot be empty") );
		
		URL = "http://localhost:8080/writeonproject/login?action=logout";
		response = CreateHandlerTest.getServletCallResponse( URL );
	}
	
	@Test
	public void createNewUserSubTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/login?user=" + m_userInfo + "&password=" + m_userInfo + "&action=login";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains( "loggedIn\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?object=usersub&userid=justine";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("error\":\"false") );
		
		URL = "http://localhost:8080/writeonproject/create?object=usersub";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"could not find user to subsribe to") );
		
		URL = "http://localhost:8080/writeonproject/login?action=logout";
		response = CreateHandlerTest.getServletCallResponse( URL );
	}
	
	@Test
	public void createNewUserTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/login?action=logout";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		
		URL = "http://localhost:8080/writeonproject/create?object=user&username=createusertest&password=createusertest&email=cs410writeon@gmail.com&firstname=fname&lastname=lname&location=vancouver&gender=male&bio=coolio";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response, response.contains("error\":\"false") );
		
		URL = "http://localhost:8080/writeonproject/create?object=user&username=createusertest&password=createusertest&email=cs410writeon@gmail.com&firstname=fname&lastname=lname&location=vancouver&gender=male&bio=coolio";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("error\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?object=user&username=";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"Must have valid username, password and email") );
	}

	@Test
	public void activateUserTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/create?object=activate&username=afsdflsjflsj&key=fsakjfdkasjfladfljafal";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"User does not exist.") );
		
		URL = "http://localhost:8080/writeonproject/create?object=activate";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("reason\":\"Must have valid username and activation key.") );
		
	}
	
	@Test
	public void createNewStoryHandlerTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/login?user=" + m_userInfo + "&password=" + m_userInfo + "&action=login";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains( "loggedIn\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?object=story&promptid=123&title=anewtitleomg&post=newpostfornewstory&tags=a,b,c,d,e";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("error\":\"false") );

		URL = "http://localhost:8080/writeonproject/login?action=logout";
		CreateHandlerTest.getServletCallResponse( URL );
	}
	
	@Test
	public void createNewPromptTest() throws IOException {
		String URL = "http://localhost:8080/writeonproject/login?user=" + m_userInfo + "&password=" + m_userInfo + "&action=login";
		String response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains( "loggedIn\":\"true") );
		
		URL = "http://localhost:8080/writeonproject/create?object=prompt&imgurl=http://www.google.com&text=abc";
		response = CreateHandlerTest.getServletCallResponse( URL );
		Assert.assertTrue( response.contains("error\":\"false") );;
		
		URL = "http://localhost:8080/writeonproject/login?action=logout";
		CreateHandlerTest.getServletCallResponse( URL );
	}
	
	/*
	 * From Lecture Slide Examples
	 */
	private static String getServletCallResponse(String URL) throws IOException {
		HttpGet httpget = new HttpGet(URL);
		httpget.setHeader("Cookie", "JSESSIONID=JUNITTESTINGID");
		HttpResponse response = httpclient.execute(httpget);
		HttpEntity entity = response.getEntity();
		char[] buf = new char[1024];
		StringBuffer str = new StringBuffer();
		if (entity != null) {
		    BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
		    int read = br.read(buf);
		    while(read != -1) {
		    	str.append(buf, 0, read);
		    	read = br.read(buf);
		    }
		    br.close();
		}
		return str.toString();
	}
	
}
